home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / µSim 1.0.5 / source / Disasm.c < prev    next >
Encoding:
Text File  |  1995-11-01  |  11.0 KB  |  425 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993,1994,1995 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11. //#pragma load "MacDump"
  12.  
  13. #pragma fourbyteints on
  14. #include    <stdlib.h>
  15. #pragma fourbyteints reset
  16.  
  17. #include    "UtilsSys7.h"
  18. #include    "Conversions.h"
  19.  
  20. #include    "Assembler.h"
  21. #include    "Compares.h"
  22. #include    "Disasm.h"
  23. #include    "Globals.h"
  24. #include    "Main.h"
  25. #include    "Microprogram_Ed.h"
  26. #include    "Input.h"
  27. #include    "Registers.h"
  28. #include    "TrackThumb.h"
  29.  
  30. #if defined(FabSystem7orlater)
  31.  
  32. //#pragma segment Main
  33.  
  34. ControlRef    disasmVScroll;
  35. static WindowRef    curPosW;
  36. short    disasmLineHeight, disasmFromTop, disasmCWidMax;
  37.  
  38. static short *DisasmInstruction(short *inst, Ptr dest, ROpcDisasmPtr instrTbl, Size TblSize);
  39. static void ThumbActionProc(ControlHandle control, short value);
  40. static pascal void DisasmActionProc(ControlHandle control, short part);
  41.  
  42. void DisasmHome(void)
  43. {
  44. SetControlValue(disasmVScroll, GetControlMinimum(disasmVScroll));
  45. InvalDisasm();
  46. }
  47.  
  48. void DisasmEnd(void)
  49. {
  50. SetControlValue(disasmVScroll, GetControlMaximum(disasmVScroll));
  51. InvalDisasm();
  52. }
  53.  
  54. void DisasmPgUp(void)
  55. {
  56. DisasmActionProc(disasmVScroll, kControlPageUpPart);
  57. }
  58.  
  59. void DisasmPgDn(void)
  60. {
  61. DisasmActionProc(disasmVScroll, kControlPageDownPart);
  62. }
  63.  
  64. /* DisasmInstruction: disassembles an instruction, returns a pointer to
  65. the next one. */
  66.  
  67. static short *DisasmInstruction(short *inst, Ptr dest, ROpcDisasmPtr instrTbl, Size TblSize)
  68. {
  69. Str15    tempS;
  70. register ROpcDisasmPtr    found;
  71. register char *tempcPtr;
  72. register short *newpos;
  73. register short    theOperand;
  74.  
  75. newpos = inst + 1;    /* at least two bytes per instruction */
  76. tempcPtr = (char *)bsearch(inst, &instrTbl->first, TblSize, sizeof(ROpcDisasm), CompareFirstLast);
  77. if (tempcPtr) {
  78.     tempcPtr -= ((char *)&instrTbl->first - (char *)instrTbl);
  79.     found = (ROpcDisasmPtr)tempcPtr;
  80.     *(OSType *)dest = found->instr;
  81.     if (found->classe != kCLASS_16_0) {    /* there is an operand */
  82.         /* extra word ? */
  83.         theOperand = ((found->classe == kCLASS_16_16) || (found->classe == kCLASS_16_16_REL)) ?
  84.                         *newpos++ : *inst & (found->last - found->first);
  85.         switch (found->classe) {    /* sign extensions for 12 & 11 bit operands */
  86.             case kCLASS_4_12:
  87.             case kCLASS_4_12_REL:
  88.                 theOperand <<= 4;
  89.                 theOperand >>= 4;
  90.                 break;
  91.             case kCLASS_5_11:
  92.                 theOperand <<= 5;
  93.                 theOperand >>= 5;
  94.                 break;
  95.             }
  96.         if (found->classe == kCLASS_4_12)
  97.             ShortToHexString(theOperand, tempS);
  98.         else
  99.             MyNumToString(theOperand, tempS);
  100.         tempcPtr = dest + 5;
  101.         if (found->classe == kCLASS_4_12)    /* hex value */
  102.             *tempcPtr++ = '$';
  103.         if (found->classe >= kCLASS_16_16_REL) {    /* relative jumps */
  104.             *tempcPtr++ = '*';
  105.             if (theOperand > 0)    /* wanna a plus sign before positive values */
  106.                 *tempcPtr++ = '+';
  107.             }
  108.         BlockMoveData(&tempS[1], tempcPtr, tempS[0]);
  109.         tempcPtr += tempS[0];
  110.         if (found->classe >= kCLASS_16_16_REL) {    /* relative jumps */
  111.             *tempcPtr++ = ' ';
  112.             *tempcPtr++ = '(';
  113.             *tempcPtr++ = '$';
  114.             tempcPtr = ShortToHexText(PTR2MEMWORD(newpos) + theOperand, tempcPtr);
  115.             *tempcPtr++ = ')';
  116.             }
  117.         }
  118.     }
  119. else {
  120.     *(OSType *)dest = 'ILL*';
  121.     }
  122. return newpos;
  123. }
  124.  
  125.  
  126. /* Activate_Disasm: handles activate events */
  127.  
  128. void Activate_Disasm(EventRecord */*evt*/, WindowPtr w, Boolean becomingActive)
  129. {
  130. Rect    growRect;
  131.  
  132. /* the growbox needs to be redrawn on activation: */
  133. growRect = w->portRect;
  134. /* adjust for the scrollbars */
  135. growRect.top = growRect.bottom - kScrollbarAdjust + 1;
  136. growRect.left = growRect.right - kScrollbarAdjust + 1;
  137. if (becomingActive) {
  138.     InvalRect(&growRect);    /* we cannot avoid grow box flicker */
  139.     if ((*disasmVScroll)->contrlVis == 0) {
  140.         ShowControl(disasmVScroll);
  141.         ValidRect(&(*disasmVScroll)->contrlRect);
  142.         }
  143.     }
  144. else {
  145. /* the control must be redrawn on deactivation: */
  146.     HideControl(disasmVScroll);
  147.     InvalRect(&growRect);
  148.     }
  149. } /*Activate*/
  150.  
  151. /* Grow_Disasm: handles resizing */
  152.  
  153. void Grow_Disasm(WindowPtr w, EventRecord *event)
  154. {
  155. Rect    tempRect, updateRect;
  156. register long    growResult;
  157.  
  158. tempRect.right = tempRect.left = PRCT_R(w) + 1;
  159. tempRect.bottom = SHRT_MAX;        /* set up limiting values */
  160. tempRect.top = kMinDocDim + 30;
  161. updateRect = w->portRect;
  162. updateRect.top = updateRect.bottom - kScrollbarAdjust;
  163. /* see if it really changed size */
  164. if (growResult = GrowWindow(w, event->where, &tempRect)) {
  165.     SizeWindow(w, LoWrd(growResult),
  166.                 (HiWrd(growResult) / disasmLineHeight) * disasmLineHeight, true);
  167.     SizeControl(disasmVScroll, kScrollbarWidth, PRCT_B(w) - PRCT_T(w) - 13);
  168.     if (HiWrd(growResult) > updateRect.bottom)
  169.         /* enlarged */
  170.         InvalRect(&updateRect);
  171.     else /* reduced */ {
  172.         updateRect.bottom = PRCT_B(w);
  173.         updateRect.right = PRCT_R(w);
  174.         updateRect.top = updateRect.bottom - kScrollbarAdjust + 1;
  175.         updateRect.left = updateRect.right - kScrollbarAdjust + 1;
  176.         InvalRect(&updateRect);
  177.         }
  178.     ValidRect(&(*disasmVScroll)->contrlRect);
  179.     SetupDisasmCtlMax(disasmVScroll);
  180.     }
  181. }
  182.  
  183. /* Update_Disasm: handles window updates. */
  184.  
  185. void Update_Disasm(WindowPtr w)
  186. {
  187. Rect    growRect;
  188. register RgnHandle    oldClip;
  189.  
  190. if (EmptyRgn(w->visRgn) == false) {    /* draw if updating needs to be done */
  191.     DrawDisasm(w);
  192.     oldClip = NewRgn();
  193.     GetClip(oldClip);
  194.     growRect = w->portRect;
  195.     growRect.left = growRect.right - kScrollbarAdjust;
  196.     ClipRect(&growRect);
  197.     DrawGrowIcon(w);
  198.     SetClip(oldClip);
  199.     DisposeRgn(oldClip);
  200.     UpdateControls(w, w->visRgn);
  201.     }
  202. }
  203.  
  204. /* Do_Disasm: we handle mouse clicks in scrollbars */
  205.  
  206. void Do_Disasm(WindowPtr w, EventRecord *event)
  207. {
  208. enum {
  209. kCurPosWindow = 128
  210. };
  211.  
  212. Rect    tempRect;
  213. GrafPtr    savePort;
  214. ControlHandle    control;
  215. Point    mouse;
  216. register short    part;
  217.  
  218. mouse = event->where;        /* get the click position */
  219. GlobalToLocal(&mouse);
  220. /* see if we are in the disasm area; if so, we won’t check the controls */
  221. tempRect = w->portRect;
  222. tempRect.right -= kScrollbarAdjust;
  223. //if (PtInRect(mouse, &tempRect)) {
  224.     /* handle editing click */
  225. /*    if ((offset = mouse.h - disasmCWidMax * 6 - kDIST_FROMLEFT) >= 0)
  226.         if ((offset /= disasmCWidMax) % 5 != 4) {
  227.             tempRect.top = (mouse.v /= dumpLineHeight) * dumpLineHeight;
  228.             tempRect.left = ((offset / 5) * 5) * dumpCWidMax + dumpCWidMax * 6 + kDIST_FROMLEFT;
  229.             tempRect.bottom = tempRect.top + dumpLineHeight;
  230.             tempRect.right = tempRect.left + (dumpCWidMax << 2);
  231.             if (TrackObject(&tempRect)) {
  232.                 clickAddr = ((unsigned long)(GetControlValue(dumpVScroll) + mouse.v) << 4)
  233.                             + ((offset / 5) << 1);
  234.                 if (DoEditDump((short *)(mMemory + clickAddr), clickAddr >> 1))
  235.                     DrawDump();
  236.                 UnloadSeg(DoEditDump);
  237.                 }
  238.             }*/
  239. //    }
  240. /*else*/ {
  241.     part = FindControl(mouse, w, &control);
  242.     switch ( part ) {
  243.         case 0:        /* do nothing for viewRect case */
  244.             break;
  245.         case kControlIndicatorPart:
  246.             GetPort(&savePort);
  247.             curPosW = GetNewWindow(kCurPosWindow, nil, (WindowPtr)-1L);
  248.             SetPortWindowPort(curPosW);
  249.             TextMode(srcCopy);
  250.             TextFont(monaco);
  251.             TextSize(9);
  252.             SetPort(savePort);
  253.             savePort = (GrafPtr)LMGetGhostWindow();
  254.             LMSetGhostWindow(curPosW);
  255.             ShowWindow(curPosW);
  256.             (void) TrackThumb(control, mouse, ThumbActionProc);
  257.             DisposeWindow(curPosW);
  258.             LMSetGhostWindow(savePort);
  259.             InvalDisasm();
  260.             break;
  261.         default:    /* clicked in an arrow, so track & scroll */
  262.             {
  263.             ControlActionUPP DisasmActionProcUPP = NewControlActionProc(DisasmActionProc);
  264.  
  265.             (void) TrackControl(control, mouse, DisasmActionProcUPP);
  266.             if (DisasmActionProcUPP)
  267.                 DisposeRoutineDescriptor(DisasmActionProcUPP);
  268.             }
  269.             break;
  270.         }
  271.     }
  272. }
  273.  
  274. /* ThumbActionProc: continuously called while we drag the scroll box */
  275.  
  276. static void ThumbActionProc(ControlHandle , short value)
  277. {
  278. Str15    tempS;
  279. GrafPtr    savePort;
  280.  
  281. ShortToHexString(value << 1, tempS);
  282. GetPort(&savePort);
  283. SetPort(curPosW);
  284. MoveTo(kDIST_FROMLEFT,12);
  285. DrawString(tempS);
  286. SetPort(savePort);
  287. }
  288.  
  289. /* DisasmActionProc: called when we hold mouse button down in some
  290. parts of the scroll bar. */
  291.  
  292. static pascal void DisasmActionProc(ControlHandle control, short part)
  293. {
  294. register WindowPtr    w;
  295. register short    amount, oldAmount;
  296.  
  297. if ( part ) {        /* if it was actually in the control */
  298.     w = (*control)->contrlOwner;
  299.     switch ( part ) {
  300.         case kControlUpButtonPart:
  301.             amount = -1;
  302.             break;
  303.         case kControlDownButtonPart:
  304.             amount = 1;
  305.             break;
  306.         case kControlPageUpPart:
  307.             amount = (PRCT_T(w) - PRCT_B(w)) / (disasmLineHeight * 2) + 1;
  308.             break;
  309.         case kControlPageDownPart:
  310.             amount = (PRCT_B(w) - PRCT_T(w)) / (disasmLineHeight * 2) - 1;
  311.             break;
  312.         }
  313.     SetControlValue(control, (oldAmount = GetControlValue(control)) + amount);
  314.     if (oldAmount != GetControlValue(control))
  315.         DrawDisasm(w);
  316.     }
  317. } /* DisasmActionProc */
  318.  
  319. /* DrawDisasm: redraws the entire Disassembler window */
  320.  
  321. void DrawDisasm(WindowPtr w)
  322. {
  323. Str27    disassembledText;
  324. Rect    tempRect, ToBeInverted;
  325. GrafPtr    savePort;
  326. Handle    tH;
  327. Point    tempPoint;
  328. short *addr;
  329. register long *clrptr;
  330. register short *textPtr;
  331. register long    spaces = 0L;
  332. short    j, HilitePC;
  333. SignedByte    savedState;
  334.  
  335. GetPort(&savePort);
  336. SetPort(w);
  337. savedState = WantThisHandleSafe(tH = Get1Resource(krInstructions, kOPCODES));
  338. tempRect = w->portRect;
  339. tempRect.bottom += disasmLineHeight;
  340. spaces = GetControlValue(disasmVScroll);
  341. addr = (short *)&gMMemory[spaces << 2];
  342. for(tempPoint.h = kDIST_FROMLEFT, j = disasmFromTop;
  343.     tempPoint.v = j, PtInRect(tempPoint, &tempRect);
  344.     j += disasmLineHeight) {
  345.  
  346.     MoveTo(PRCT_L(w) + kDIST_FROMLEFT, j);
  347.     clrptr = (long *)&disassembledText;
  348.     spaces = '    ';
  349.     *clrptr++ = spaces;
  350.     *clrptr++ = spaces;
  351.     *clrptr++ = spaces;
  352.     *clrptr++ = spaces;
  353.     *clrptr++ = spaces;
  354.     *clrptr++ = spaces;
  355.     *clrptr = spaces;
  356.     textPtr = (short *)ShortToHexText(HilitePC = PTR2MEMWORD(addr), (Ptr)&disassembledText);
  357.     *textPtr++ = ': ';
  358.     addr = DisasmInstruction(addr, (Ptr)textPtr, (ROpcDisasmPtr)((*tH) + 2), *(unsigned short *)*tH + 1);
  359.  
  360.     DrawText(&disassembledText, 0L, 28L);
  361.     if (HilitePC == gRegs[kREG_PC]) {
  362.         ToBeInverted.top = j - disasmLineHeight + 1;
  363.         ToBeInverted.left = PRCT_L(w) + kDIST_FROMLEFT;
  364.         ToBeInverted.bottom = j + 1;
  365.         ToBeInverted.right = ToBeInverted.left + disasmCWidMax * kMaxCharsInOneDisasmLine;
  366.         LMSetHiliteMode(LMGetHiliteMode() & 0x7F);
  367.         InvertRect(&ToBeInverted);
  368.         }
  369.     }
  370. HSetState(tH, savedState);
  371. SetPort(savePort);
  372. }
  373.  
  374. /* SetupDisasmCtlMax: sets up the CtlMax value of our scroll bar */
  375.  
  376. void SetupDisasmCtlMax(ControlHandle theControl)
  377. {
  378. enum {
  379. kAdjustForPleasantGrow = 3
  380. };
  381.  
  382. register WindowRef    wind;
  383. register short    newmax;
  384.  
  385. wind = (*theControl)->contrlOwner;
  386. newmax = SHRT_MAX - (PRCT_B(wind) - PRCT_T(wind) - kAdjustForPleasantGrow) / (disasmLineHeight << 1);
  387. if (newmax != GetControlMaximum(theControl)) {
  388.     SetControlMaximum(theControl, newmax);
  389.     InvalDisasm();
  390.     }
  391. }
  392.  
  393. /* InvalDisasm: invalidates the entire window contents
  394. (excluding the scrollbar) */
  395.  
  396. void InvalDisasm(void)
  397. {
  398. Rect    tempRect;
  399. GrafPtr    savePort;
  400.  
  401. GetPort(&savePort);
  402. SetPortWindowPort(gWPtr_Disasm);
  403. tempRect = gWPtr_Disasm->portRect;
  404. tempRect.right -= kScrollbarWidth;
  405. InvalRect(&tempRect);
  406. SetPort(savePort);
  407. }
  408.  
  409. /* procedure called when closing the Disasm window */
  410.  
  411. void CloseDisasm(WindowPtr w)
  412. {
  413. DoCloseWindow(w, kMItem_Disasm);
  414. }
  415.  
  416. void getDragRectDisasm(WindowPtr w, RectPtr r)
  417. {
  418. *r = w->portRect;
  419. r->right -= kScrollbarAdjust;
  420. }
  421.  
  422.  
  423. #endif
  424.  
  425.